package com.irain.pp.tool.mybatis.mgmt;

import com.irain.pp.tool.api.cache.DataObjectCache;
import com.irain.pp.tool.api.cache.GetFunction;
import com.irain.pp.tool.api.data.DataObject;
import com.irain.pp.tool.annotation.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * @author WangYanPeng
 * @date 2017/10/29 0:46
 */
public abstract class BaseCacheManagerImpl<DO extends DataObject> extends BaseDataManagerImpl<DO>
        implements BaseManager<DO> {

    protected long expired = 1296000;

    @Autowired
    private DataObjectCache dataObjectCache;

    @Override
    public DO selectById(Long id) {
        if (id == null) return null;
        return dataObjectCache.getData(doClass, id, () -> super.selectById(id), expired);
    }

    @Override
    public void updateById(@NotNull DO data) {
        try {
            super.updateById(data);
        } finally {
            dataObjectCache.saveData(doClass, data.getId(), super.selectById(data.getId()), expired);
        }
    }

    @Override
    public void updateByIdSelective(@NotNull DO data) {
        try {
            super.updateByIdSelective(data);
        } finally {
            dataObjectCache.saveData(doClass, data.getId(), super.selectById(data.getId()), expired);
        }
    }

    @Override
    public void updateOneByExample(@NotNull DO data, @NotNull Example example) {
        try {
            super.updateOneByExample(data, example);
        } finally {
            dataObjectCache.saveData(doClass, data.getId(), super.selectById(data.getId()), expired);
        }
    }

    @Override
    public void updateOneByExampleSelective(@NotNull Long id, @NotNull DO data, @NotNull Example example) {
        try {
            super.updateOneByExampleSelective(id, data, example);
        } finally {
            dataObjectCache.saveData(doClass, data.getId(), super.selectById(data.getId()), expired);
        }
    }

    @Override
    protected int updateByExampleSelective(@NotNull DO record, Example example, Integer checkNum) {
        try {
            return super.updateByExampleSelective(record, example, checkNum);
        } finally {
            List<DO> list = super.selectByExample(example);
            list.forEach(item -> dataObjectCache.saveData(doClass, item.getId(), item, expired));
        }
    }

    @Override
    public boolean deleteById(@NotNull Long id) {
        boolean result = super.deleteById(id);
        dataObjectCache.deleteData(doClass, id);
        return result;
    }

    @Override
    @Deprecated
    protected int deleteByExample(@NotNull Object example) {
        throw new UnsupportedOperationException();
    }

    @NotNull
    @Override
    public void insert(@NotNull DO dataObject) {
        super.insert(dataObject);
        dataObjectCache.saveData(doClass, dataObject.getId(), dataObject, expired);
    }

    public Long getIdByCache(String property, Object[] params, GetFunction<DO> getIfAbsent) {
        return dataObjectCache.getId(doClass, property, params, getIfAbsent, expired);
    }

    public void saveIdByCache(String property, Object[] params, Long id) {
        dataObjectCache.saveId(doClass, property, params, id, expired);
    }

    public void deleteIdByCache(String property, Object[] params) {
        dataObjectCache.deleteId(doClass, property, params);
    }


}
